package com.yuanian.timingwheel.respository.po;

import com.alibaba.fastjson.JSONObject;

import com.yuanian.timingwheel.context.ExecutionContext;
import com.yuanian.timingwheel.context.SpringContext;
import com.yuanian.timingwheel.dao.LivingServerDao;
import com.yuanian.timingwheel.dao.TaskDao;
import com.yuanian.timingwheel.infrastructure.DateUtils;
import com.yuanian.timingwheel.model.task.base.BaseTask;
import com.yuanian.timingwheel.model.task.base.TaskExecutionResult;
import com.yuanian.timingwheel.model.task.executetask.LocalTaskExecutor;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

//@TableName(value = "TP_TW_TASK")
public class TaskEntity {

    //@TableId(type = IdType.AUTO)
    private Long id;

    private String businessId;

    private String taskDesc;
    //任务类型,1自动0手工
    private int type;
    //间隔秒数
    private Long executionInterval;
    //执行次数
    private Long executionRounds;
    //下次执行时间
    private Date executionTime;
    //已经执行次数
    private Long executedRounds;

    //执行的方法
   // @DbJson
    //@TableField(typeHandler = JacksonTypeHandler.class)
    private LocalTaskExecutor taskMethod;

    //附属任务
    //@DbJson
    //@TableField(typeHandler = JacksonTypeHandler.class)
    private List<TaskEntity> attachTaskList;

    private boolean isSuccess;

    private String exceptionMsg;

    private Date createTime;

    private Date updateTime;

    //@SoftDelete
    private boolean deleted = false;
    //0正常1暂停
    private Integer status;

    public String getBusinessId() {
        return businessId;
    }

    public void setBusinessId(String businessId) {
        this.businessId = businessId;
    }

    public String getTaskDesc() {
        return taskDesc;
    }

    public void setTaskDesc(String taskDesc) {
        this.taskDesc = taskDesc;
    }

    public boolean isDeleted() {
        return deleted;
    }

    public void setDeleted(boolean deleted) {
        this.deleted = deleted;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public Long getExecutionInterval() {
        return executionInterval;
    }

    public void setExecutionInterval(Long executionInterval) {
        this.executionInterval = executionInterval;
    }

    public Long getExecutionRounds() {
        return executionRounds;
    }

    public void setExecutionRounds(Long executionRounds) {
        this.executionRounds = executionRounds;
    }

    public Date getExecutionTime() {
        return executionTime;
    }

    public void setExecutionTime(Date executionTime) {
        this.executionTime = executionTime;
    }

    public Long getExecutedRounds() {
        return executedRounds;
    }

    public void setExecutedRounds(Long executedRounds) {
        this.executedRounds = executedRounds;
    }

    public LocalTaskExecutor getTaskMethod() {
        return taskMethod;
    }

    public void setTaskMethod(LocalTaskExecutor localTaskExecutor) {
        this.taskMethod = localTaskExecutor;
    }

    public List<TaskEntity> getAttachTaskList() {
        return attachTaskList;
    }

    public void setAttachTaskList(List<TaskEntity> attachTaskList) {
        this.attachTaskList = attachTaskList;
    }

    public boolean isSuccess() {
        return isSuccess;
    }

    public void setSuccess(boolean success) {
        isSuccess = success;
    }

    public String getExceptionMsg() {
        return exceptionMsg;
    }

    public void setExceptionMsg(String exceptionMsg) {
        this.exceptionMsg = exceptionMsg;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public static void save(BaseTask task) {
        TaskEntity taskEntity = task2TaskEntity(task);
        if (task.getAttachTaskList() != null) {
            List<TaskEntity> list = new ArrayList<>();
            for (BaseTask attachTask : task.getAttachTaskList()) {
                TaskEntity attachTaskEntity = task2TaskEntity(attachTask);
                list.add(attachTaskEntity);
            }
            taskEntity.setAttachTaskList(list);
        }
        SpringContext.getBean(TaskDao.class).save(taskEntity);
        //taskEntity.save();
        //反写ID
        task.setId(taskEntity.getId());
    }

    public static TaskEntity task2TaskEntity(BaseTask task) {
        TaskEntity taskEntity = new TaskEntity();
        taskEntity.setBusinessId(task.getBusinessId());
        taskEntity.setTaskDesc(task.getTaskDesc());
        taskEntity.setType(task.getType());
        taskEntity.setExecutionInterval(task.getTaskInfo().getExecutionInterval());
        taskEntity.setExecutedRounds(task.getTaskInfo().getExecutedRounds());
        taskEntity.setExecutionRounds(task.getTaskInfo().getExecutionRounds());
        taskEntity.setExecutionTime(task.getTaskInfo().getExecutionTime());
        taskEntity.setTaskMethod(task.getTaskMethod());
        //taskEntity.setAttachTaskList(task.getAttachTaskList());
        taskEntity.setCreateTime(new Date());
        taskEntity.setStatus(0);
        return taskEntity;
    }

    /**
     * 获取当前23:59:59之前的任务
     * @return
     */
    public static List<TaskEntity> getEndOfDayTask() {
        return getEndOfDayTask(new Date());
    }

    /**
     * 获取当前23:59:59之前的任务
     * @return
     */
    public static List<TaskEntity> getEndOfDayTask(Date date) {
        //return SpringContext.getBean(Database.class).find(TaskEntity.class).where().le("executionTime", date).ne("isSuccess", true).notIn("id", ExecutionContext.getInstance().getLivingServer().getLoadTaskIds()).findList();
        /*QTaskEntity qTaskEntity = new QTaskEntity();
        //查询没执行成功，当天23:59:59，并且没有加载过的数据
        List<TaskEntity> list = qTaskEntity.executionTime.lessOrEqualTo(DateUtils.getEndOfDay(date)).isSuccess.ne(true).id.notIn(ExecutionContext.getInstance().getLivingServer().getLoadTaskIds()).findList();
        return list;*/
        return SpringContext.getBean(TaskDao.class).getEndOfDayTask(DateUtils.getEndOfDay(date));
    }

    public static void update(BaseTask baseTask) {
        TaskEntity taskEntity = new TaskEntity();
        taskEntity.setId(baseTask.getId());
        taskEntity.setExecutedRounds(baseTask.getTaskInfo().getExecutedRounds());
        taskEntity.setUpdateTime(new Date());
        taskEntity.setExecutionTime(baseTask.getTaskInfo().getExecutionTime());
        TaskExecutionResult taskExecutionResult = baseTask.getTaskExecutionResult();
        if (taskExecutionResult != null) {
            taskEntity.setSuccess(taskExecutionResult.isSuccess());
            if (taskExecutionResult.isSuccess()) {
                taskEntity.setExceptionMsg(JSONObject.toJSONString(taskExecutionResult.getResult()));
            } else {
                taskEntity.setExceptionMsg(taskExecutionResult.getExceptionMsg());
            }

        }
        //taskEntity.update();
        int rowNum = SpringContext.getBean(TaskDao.class).update(taskEntity);
        System.out.println("update num------" + rowNum);
    }

    public static TaskEntity getTaskByID(Long taskId, boolean deleted) {
        return null;
        //return SpringContext.getBean(Database.class).find(TaskEntity.class).where().eq("id", taskId).eq("deleted", deleted).findOne();
        /*QTaskEntity qTaskEntity = new QTaskEntity();
        return qTaskEntity.id.eq(taskId).deleted.eq(deleted).findOne();*/
        //return null;
    }

    public static TaskEntity getTaskByID(Long taskId) {
        /*QTaskEntity qTaskEntity = new QTaskEntity();
        return qTaskEntity.id.eq(taskId).findOne();*/
        //return SpringContext.getBean(Database.class).find(TaskEntity.class).where().eq("id", taskId).findOne();
        return SpringContext.getBean(TaskDao.class).getTaskByID(taskId);
    }

    public static TaskEntity getTaskByID(String businessId) {
       /* QTaskEntity qTaskEntity = new QTaskEntity();
        return qTaskEntity.businessId.eq(businessIdId).findOne();*/
        //return SpringContext.getBean(Database.class).find(TaskEntity.class).where().eq("businessId", businessId).findOne();
        return SpringContext.getBean(TaskDao.class).getTaskByBusinessId(businessId);
    }

    public static void delete(TaskEntity taskEntity) {
       /* taskEntity.setDeleted(true);
        taskEntity.update();*/
        SpringContext.getBean(TaskDao.class).delete(taskEntity.getId());
    }

    public static void suspendOrResume(TaskEntity taskEntity, boolean suspend) {
        /*taskEntity.setStatus(suspend ? 1 : 0);
        taskEntity.update();*/
        SpringContext.getBean(TaskDao.class).suspendOrResume(suspend ? 1 : 0, taskEntity.getId());
    }

    public static void update(TaskEntity taskEntity, Date executionTime) {
        /*taskEntity.setExecutionTime(executionTime);
        taskEntity.update();*/
        SpringContext.getBean(TaskDao.class).updateExecutionTime(executionTime, taskEntity.getId());
    }

    public static TaskEntity getAutoTaskByDesc(String desc) {
        //QTaskEntity qTaskEntity = new QTaskEntity();
        //return qTaskEntity.taskDesc.eq(desc).type.eq(1).findOne();
        //return SpringContext.getBean(Database.class).find(TaskEntity.class).where().eq("taskDesc", desc).eq("type", 1).findOne();
        return null;
    }

    public static List<TaskEntity> getAutoTask() {
        return SpringContext.getBean(TaskDao.class).getAutoTask();
        ///return SpringContext.getBean(Database.class).find(TaskEntity.class).where().eq("type", 1).findList();
        /*QTaskEntity qTaskEntity = new QTaskEntity();
        return qTaskEntity.type.eq(1).findList();*/
    }

    /**
     * 获取当前23:59:59之前的任务
     * @return
     */
    public static List<TaskEntity> getDateTask(Date date) {
       /* QTaskEntity qTaskEntity = new QTaskEntity();
        List<TaskEntity> list = qTaskEntity.executionTime.eq(date).deleted.eq(false).findList();
        return list;*/
        return null;
    }
}
